package cn.bonoon.kernel.support;

import cn.bonoon.core.ILoginEditor;
import cn.bonoon.kernel.exceptions.PasswordVerifierException;
import cn.bonoon.kernel.support.entities.EntityLoginable;

/**
 * 专门用来验证密码的算法
 * @author jackson
 *
 */
public interface PasswordVerifier {
	/**
	 * 
	 * @param entity
	 * @param editor 存放的密码和验证的密码应该是明文密码
	 * @throws PasswordVerifierException
	 */
	void set(EntityLoginable entity, ILoginEditor editor) throws PasswordVerifierException;
	
	/**
	 * 
	 * 注意，这里要求传进来的是明文的密码
	 * @param entity
	 * @param pwd 明文密码
	 * @param repwd 明文密码
	 * @throws PasswordVerifierException
	 */
	void setPassword(EntityLoginable entity, String pwd, String repwd) throws PasswordVerifierException;
	/**
	 * 
	 * 注意，这里要求传进来的新密码应该是明文的密码，旧的密码应该为已经加密的MD5码
	 * @param entity
	 * @param oldPwd
	 * @param pwd 明文密码
	 * @param repwd 明文密码
	 * @throws PasswordVerifierException
	 */
	void resetPassword(EntityLoginable entity, String oldPwd, String pwd, String repwd)throws PasswordVerifierException;
	
	/**
	 * 注意，这里要求传进来的是明文的密码
	 * @param pwd 明文密码
	 * @param repwd 明文密码
	 * @return
	 * @throws PasswordVerifierException
	 */
	String verify(String pwd, String repwd)throws PasswordVerifierException;
	String randomPassword(EntityLoginable entity)throws PasswordVerifierException;
	
	void setLoginName(EntityLoginable entity, String loginName) throws PasswordVerifierException;
	String verify(String loginName) throws PasswordVerifierException;
	
	/**
	 * 检查密码是否符合指定的规则，并对密码进行加密处理
	 * 
	 * 这里要求的是明文的密码
	 * @param pwd 未加密的源密码
	 * @return 加密后的密码
	 * @throws PasswordVerifierException
	 */
	String checkAndEncode(String pwd) throws PasswordVerifierException;
	
	/**
	 * 用于判断密码是否相等，直接代理{@link org.springframework.security.crypto.password.PasswordEncoder PasswordEncoder}
	 * @param rawPassword 需要被判断的密码，一般由用户输入
	 * @param encodedPassword 已经存储的加密的密码
	 * @return 是否相同
	 */
	boolean matches(CharSequence rawPassword, String encodedPassword);
	
	/**
	 * 只对密码进行加密处理，直接代理{@link org.springframework.security.crypto.password.PasswordEncoder PasswordEncoder}
	 * 
	 * 注意这里传进来的应该是已经经过了第一次加密的MD5码
	 * @param rawPassword 未加密的源密码
	 * @return 加密后的密码
	 */
	String encode(CharSequence rawPassword);
}
